#include "Thread.hpp"
#include "RingQueue.hpp"
#include <vector>

// void Print(int a)
// {
//     int cnt = 10;
//     while(cnt--)
//     {
//         std::cout << "a = " << a << std::endl;
//         sleep(1);
//     }
// }

// int main()
// {
//     int a =10;
//     std::string name = "Thread-1";
//     std::function<void(int&)> f = Print;
//     Thread<int> thread(Print,a);
//     return 0;
// }
using ringqueue_t = RingQueue<int>;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void productor(ringqueue_t &rq, const std::string name) // 生产者执行的工作
{
    
    while (true)
    {
        int data = rand() % 10;
        rq.Enqueue(data);
        std::cout << "name : " << name << "enqueue seccess! data : " << data << std::endl;
    }
}
void consumer(ringqueue_t &rq, const std::string name) // 消费者执行的工作
{
    int data;
    while (true)
    {
        rq.Pop(data);
        std::cout << "name : " << name << "Pop success! data : " << data << std::endl;
    }
}
void StartCommon(func_t<ringqueue_t> func, int num, std::vector<Thread<ringqueue_t>> &threads, ringqueue_t &rq,std::string mode)
{
    for (int i = 0; i < num; ++i)
    {
        usleep(1000);
        std::string name = mode + "thread-" + std::to_string(i + 1);
        threads.emplace_back(func, rq, name);
    }
}
void StartConsumer(int num, std::vector<Thread<ringqueue_t>> &threads, ringqueue_t &rq)
{
    StartCommon(consumer, num, threads, rq,"consumer：");
}
void StartProductor(int num, std::vector<Thread<ringqueue_t>> &threads, ringqueue_t &rq)
{
    StartCommon(productor, num, threads, rq,"productor：");
}
void WaitAll(std::vector<Thread<ringqueue_t>> &threads)
{
    for (auto &thread : threads)
    {
        thread.Join();
    }
}

int main()
{
    ringqueue_t *ring_queue = new ringqueue_t(10);       // 后续生产者和消费者看到的同一个阻塞队列
    int productor_num = 5;                               // 生产者个数
    int consumer_num = 3;                                // 消费者个数
    std::vector<Thread<ringqueue_t>> threads;            // 管理所有的生产者和消费者
    StartProductor(productor_num, threads, *ring_queue); // 启动所有的生产者
    StartConsumer(consumer_num, threads, *ring_queue);   // 启动所有的消费者
    WaitAll(threads);                                    // 等待所有线程
    return 0;
}
